package cn.ulc.socket.weapp.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaQrcodeService;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.ulc.common.constant.PubDataConstant;
import cn.ulc.common.constant.enums.AvailableStatus;
import cn.ulc.common.constant.enums.DeletedStatus;
import cn.ulc.common.constant.enums.ResultCode;
import cn.ulc.common.exception.PlatformException;
import cn.ulc.common.util.AliyunOssFileUtil;
import cn.ulc.common.util.ConvertUtil;
import cn.ulc.common.util.JwtUtil;
import cn.ulc.common.util.UserUtils;
import cn.ulc.socket.weapp.common.BaseService;
import cn.ulc.socket.weapp.model.dto.WxUserDTO;
import cn.ulc.socket.weapp.model.param.WxUserParam;
import cn.ulc.socket.weapp.service.AccountService;
import cn.ulc.store.dao.CompanyDao;
import cn.ulc.store.dao.SetInfoDao;
import cn.ulc.store.dao.sign.SignDao;
import cn.ulc.store.dao.user.MemberDao;
import cn.ulc.store.dao.user.WeixinUserDao;
import cn.ulc.store.entity.Company;
import cn.ulc.store.entity.SetInfo;
import cn.ulc.store.entity.sign.Sign;
import cn.ulc.store.entity.user.Member;
import cn.ulc.store.entity.user.WeixinUser;
import io.jsonwebtoken.Claims;
import lombok.AllArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.math.BigDecimal;
import java.util.Date;

@Service
@AllArgsConstructor
public class AccountServiceImpl extends BaseService implements AccountService {

  WeixinUserDao userDao;
  WxMaService wxMaService;
  MemberDao memberDao;
  CompanyDao companyDao;
  SetInfoDao setInfoDao;
  SignDao signDao;
  @Override
  public String login(String code,Long companyId) {
    String openId = "";
    String sessionKey = "";
    try {
      WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(code);
      openId = session.getOpenid();
      sessionKey = session.getSessionKey();
      if(StringUtils.isBlank(openId) || StringUtils.isBlank(sessionKey)) throw new PlatformException(ResultCode.FAIL.getCode(),"未获得微信信息");
      WeixinUser user = userDao.findByOpenId(openId);
      Boolean isNew = false;
      if(user == null || user.getId() == null){
        user = new WeixinUser();
        user.setCreateAt(DateUtil.date());
        user.setDeleted( DeletedStatus.UN_DELETED);
        user.setOpenId(openId);
        user.setCompanyId(companyId);
        user.setLoginCount(0);
        isNew = true;
      }else{
        user.setModifyAt(DateUtil.date());
      }
      user.setSessionkey(sessionKey);
      userDao.save(user);
      if(isNew){
        //创建签到
        Sign sign = new Sign();
        sign.setDeleted(DeletedStatus.UN_DELETED);
        sign.setCreateAt(new Date());
        sign.setCompanyId(companyId);
        sign.setWxUserId(user.getId());
        sign.setAmount(BigDecimal.ZERO);
        sign.setDays(0);
        sign.setContinuityDays(0);
        signDao.save(sign);
      }
      UserUtils.setUser(user);
      String token = JwtUtil.createJWT(user.getId(),user.getCompanyId(), PubDataConstant.LOGIN_WX_USER);
      return token;
    }catch (Exception e){
      throw new PlatformException(ResultCode.FAIL.getCode(),"token过期");
    }
  }

  @Override
  public WxUserDTO bind(WxUserParam param, String token) {
    Claims claims = JwtUtil.parseJwtToken(token);
    Long userId = 0l, companyId = 0l;
    if (claims != null) {
      userId = ConvertUtil.toLong(claims.get("userId"));
      companyId = ConvertUtil.toLong(claims.get("companyId"));
    }
    if (userId == null || userId <= 0 || companyId == null || companyId <= 0) throw new PlatformException(ResultCode.FAIL.getCode(), "验证用户信息失败");
    WeixinUser weixinUser = userDao.findOne(userId);
    Company company = companyDao.findOne(companyId);
    if (weixinUser == null || company == null ) throw new PlatformException(ResultCode.FAIL.getCode(), "验证用户信息失败");

    String sessionKey = weixinUser.getSessionkey();
    String rawData = param.getRawData();
    String signature = param.getSignature();
    String encryptedData = param.getEncryptedData();
    String iv = param.getIv();

    // 用户信息校验
    if (!wxMaService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
      throw new RuntimeException("check user failed,数据签名校验失败 ");
    }
    // 解密用户信息
    WxMaUserInfo userInfo = wxMaService.getUserService().getUserInfo(sessionKey, encryptedData, iv);
    if (userInfo == null) {
      throw new RuntimeException("登录失败");
    }
    weixinUser.setCountry(userInfo.getCountry());
    weixinUser.setProvince(userInfo.getProvince());
    weixinUser.setCity(userInfo.getCity());
    weixinUser.setHeadImgUrl(userInfo.getAvatarUrl());
    weixinUser.setNickName(userInfo.getNickName());
    weixinUser.setUserLang(userInfo.getLanguage());
    weixinUser.setLoginCount(weixinUser.getLoginCount()+1);
    int gender = ConvertUtil.toInteger(userInfo.getGender());
    String sex = "其他";
    if (gender == 1) sex = "男";
    if (gender == 2) sex = "女";
    weixinUser.setSex(sex);
    userDao.save(weixinUser);
    Member member = memberDao.findByWxUserId(weixinUser.getId(),AvailableStatus.AVAILABLE);
    SetInfo setInfo = setInfoDao.findByCondition(companyId);
    return WxUserDTO.builder().setInfo(setInfo).company(company).member(member).user(weixinUser).build();
  }

  @Override
  public String generateWxQrCode(String scene, String page) {
    if(StrUtil.isBlank(scene) || StrUtil.isBlank(page)) throw new PlatformException("生成小程序码参数错误");
    WxMaQrcodeService wxMaQrcodeService = wxMaService.getQrcodeService();
    try{
      File qrCode = wxMaQrcodeService.createWxaCodeUnlimit(scene,page);
      String path = AliyunOssFileUtil.uploadPublicFile(qrCode, DateUtil.currentSeconds()+"","/store");
      return path;
    }catch (Exception e) {
      e.printStackTrace();
      throw new PlatformException("生成小程序异常");
    }
  }
}
